﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Web.Mvc;
using AgileBoard.Domain;
using AgileBoard.Dtos;
using AgileBoard.Dtos.Mappers;
using AgileBoard.Web.Controllers.Util;

namespace AgileBoard.Web.Controllers
{
    public class StatusController : BaseController
    {
        // POST: /Status/Index/IterationId

        [AcceptVerbs(HttpVerbs.Post), Authorize]
        public ActionResult Index(Guid iterationId)
        {
            var rdto = new ResultDTO();
            double count = 0.0;
            double evaluation = 0.0, remaining = 0.0;
            var config = new StringBuilder();

            Iteration Iteration = ManagerFactory.IterationManager.Get(iterationId);
            IList Statuss = ManagerFactory.StatusManager.GetAll();
            IList Actuals = ManagerFactory.ActualsManager.GetAll();
            IList Tasks = ManagerFactory.TaskManager.GetByIteration(Iteration.IterationID.ToString());
            IList Labels = ManagerFactory.LabelManager.GetByIteration(Iteration.IterationID.ToString());

            // add one default release, if not found
            if (Statuss.Count == 0)
            {
                Status toDo = ManagerFactory.StatusManager.NewStatus();
                toDo.Name = "NotDone";
                toDo = ManagerFactory.StatusManager.Save(toDo);

                Status inProgress = ManagerFactory.StatusManager.NewStatus();
                inProgress.Name = "InProgress";
                inProgress = ManagerFactory.StatusManager.Save(inProgress);

                Status onTest = ManagerFactory.StatusManager.NewStatus();
                onTest.Name = "On Test";
                onTest = ManagerFactory.StatusManager.Save(onTest);

                Status done = ManagerFactory.StatusManager.NewStatus();
                done.Name = "Done";
                done = ManagerFactory.StatusManager.Save(done);

                Statuss.Add(toDo);
                Statuss.Add(inProgress);
                Statuss.Add(onTest);
                Statuss.Add(done);
            }

            foreach (Task task in Tasks)
            {
                foreach (Label label in Labels)
                {
                    if (task.CreateTime >= Convert.ToDateTime(label.Date) ||
                        Convert.ToDateTime(label.Date) > DateTime.Now) continue;
                    IList actuals = ManagerFactory.ActualsManager.GetByLabel(label.LabelID.ToString());
                    Boolean exits = false;

                    foreach (Actual actual in actuals)
                    {
                        if (actual.TaskID.ToLower() == task.TaskID.ToString().ToLower()) exits = true;
                    }

                    if (!exits)
                    {
                        Actual newActual = ManagerFactory.ActualsManager.NewActual();
                        newActual.TaskID = task.TaskID.ToString();
                        newActual.Label = label;
                        newActual.Remain = task.Remaining;
                        newActual = ManagerFactory.ActualsManager.Save(newActual);
                        task.AddActual(newActual);
                    }
                }
            }

            IList<StatusDTO> StatusDTO = new List<StatusDTO>();
            foreach (Status Status in Statuss)
            {
                foreach (Task task in Tasks)
                {
                    if (task.Status.StatusID == Status.StatusID && new Guid(task.IterationID) == iterationId)
                    {
                        Status.AddTask(task);
                        count++;
                        evaluation += task.Evaluation;
                        remaining += task.Remaining;
                    }
                }

                StatusDTO StatusDto = StatusDTOMapper.MapToDTO(Status);

                foreach (Task task in Tasks)
                {
                    if (task.Status.StatusID == Status.StatusID && new Guid(task.IterationID) == iterationId)
                    {
                        Status.RemoveTask(task);
                    }
                }

                //StatusDto.TaskCount = count;
                //StatusDto.EvaluationSum = evaluation;
                //StatusDto.RemainingSum = remaining;
                StatusDTO.Add(StatusDto);

                count = evaluation = remaining = 0.0;
            }

            rdto.Data = StatusDTO.ToExtJsJson("items", "totalCount");
            rdto.Result = true;
            rdto.Message = "Success";

            return Json(rdto);
        }

        // POST: /Status/Add/Json, Update

        [AcceptVerbs(HttpVerbs.Post), Authorize]
        public ActionResult Add(StatusDTO Json, Boolean Update)
        {
            var rdto = new ResultDTO();
            Status newStatus = StatusDTOMapper.MapFromDTO(Json);

            if (!Update)
            {
                //initialize new release default data
                newStatus.Name = "New Status";
                newStatus.CreateTime = DateTime.Now;
            }

            try
            {
                newStatus = ManagerFactory.StatusManager.Update(newStatus);
                rdto.Message = "Success";
                rdto.Result = true;
                rdto.Data = StatusDTOMapper.MapToDTO(newStatus).ToExtJsJson();
                ;
            }
            catch (Exception e)
            {
                rdto.Message = e.Message;
                rdto.Result = false;
            }

            return this.Json(rdto);
        }

        // POST: /Status/Delete/GUID

        [AcceptVerbs(HttpVerbs.Post), Authorize]
        public ActionResult Delete(Guid Guid)
        {
            var rdto = new ResultDTO();
            try
            {
                if (ManagerFactory.TaskManager.GetByStatus(Guid.ToString()).Count > 0)
                    throw new Exception("Status which contains task cannot be removed.");

                ManagerFactory.StatusManager.Delete(Guid);
                rdto.Message = "Success";
                rdto.Result = true;
            }
            catch (Exception ex)
            {
                rdto.Message = ex.Message;
                rdto.Result = false;
            }
            return Json(rdto);
        }
    }
}